package com.tingyuge.thinking.spring.configuration.bean.definition;

import com.tingyuge.thinking.spring.ioc.overview.domain.User;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.Map;

import static org.springframework.beans.factory.support.BeanDefinitionBuilder.genericBeanDefinition;

/**
 * 注解 beanDefiniton 示例
 * @author xiaodao
 * @version 1.0
 * @date 2021/6/15
 */
@Import(AnnotationBeanDefinitionDemo.Config.class)
public class AnnotationBeanDefinitionDemo {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        //注册 configuration class（配置类）
        applicationContext.register(Config.class);
        //通过BeanDefinition 注册API 方式
        //1.命名 bean注册方式
        registryUserBeanDefinition(applicationContext, "xiaodao-user");
        //2.非命名bean 注册方式
        registryUserBeanDefinition(applicationContext);
        //启动应用上下文
        applicationContext.refresh();
        //1.通过 @bean方式定义
        //2.通过 @Component 方式
        //3. 通过@import 方式
        Map<String, Config> beans = applicationContext.getBeansOfType(Config.class);
        System.out.println("config bean 所有的bean "+ beans);
        Map<String, User> userBeans = applicationContext.getBeansOfType(User.class);
        System.out.println("user bean 所有的bean "+ userBeans);
        //显示关闭应用上下文
        applicationContext.close();
    }

    /**
     * 命名Bean 的注册方式
     * @param beanDefinitionRegistry
     * @param beanName
     */
    public static void registryUserBeanDefinition(BeanDefinitionRegistry beanDefinitionRegistry,String beanName){
        BeanDefinitionBuilder beanDefinitionBuilder = genericBeanDefinition(User.class);
        beanDefinitionBuilder.addPropertyValue("id", 1)
                .addPropertyValue("name", "xiaodao");
        //判断如果beanName 存在时
        if(StringUtils.hasText(beanName)){
            beanDefinitionRegistry.registerBeanDefinition(beanName,beanDefinitionBuilder.getBeanDefinition());
        }else{
            //非命名方式 注册
            BeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinitionBuilder.getBeanDefinition(),beanDefinitionRegistry);
        }

    }
    public static void registryUserBeanDefinition(BeanDefinitionRegistry beanDefinitionRegistry){
        registryUserBeanDefinition(beanDefinitionRegistry, null);
    }
    //2.通过 @Component 方式
    //定义当前类作为 spring bean（组件）
    @Component
    public static class Config{

        //1.通过 @bean方式定义
        @Bean(name = {"user","xx-user"})
        public User user(){
            User user = new User();
            user.setName("小刀");
            return user;
        }
    }
}
